/*******************************************************************************
 * Copyright (c) 2010 European Software Institute - Tecnalia.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@esi.es)
 *     
 *******************************************************************************/
package es.esi.gemde.modeltransformator.service.impl;

import java.io.File;
import java.net.URI;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Vector;

import org.eclipse.emf.ecore.EClass;

import es.esi.gemde.modeltransformator.service.ITransformation;
import es.esi.gemde.modeltransformator.service.ITransformationEngine;
import es.esi.gemde.modeltransformator.service.TransformationFactory;

/**
 * Implementation of the {@link ITransformation} interface.
 *
 * @author Adrian Noguero (adrian.noguero@tecnalia.com)
 * @version 1.0
 * @since 1.0
 *
 */
public class Transformation implements ITransformation {

	private HashMap<String, String> options;
	private String name;
	private String description;
	private ITransformationEngine engine;
	private List<URI> transformationURIs;
	private ResourceType type = ResourceType.NORMAL;
	private LinkedHashMap<String, EClass> inputs;
	private LinkedHashMap<String, EClass> outputs;
	
	/**
	 * Constructor of the class. 
	 * Not intended to be used. To create instances use {@link TransformationFactory} instead.
	 *
	 * @param name the name of the transformation.
	 * @param engine the engine that will run this transformation.
	 * @param uris the List of URIs that contain the transformation specifications.
	 * @param description the textual description of this transformation. Can be null.
	 * @param isProtected if true the transformation will be considered session protected. If false it will be treated normally.
	 * @param inputs a list with the types of the inputs required by this transformation.
	 *
	 * @see {@link TransformationFactory#createTransformation(String, String, File, String)}
	 */
	public Transformation(String name, ITransformationEngine engine, List<URI> uris, String description, ResourceType type, List<EClass> inputs) {
		this.name = name;
		this.engine = engine;
		this.transformationURIs = uris;
		this.inputs = new LinkedHashMap<String, EClass>();
		this.outputs = new LinkedHashMap<String, EClass>();
		if (description == null) {
			this.description = "";
		}
		else {
			this.description = description;
		}
		this.type = type;
		Integer counter = 0;
		for (EClass i : inputs) {
			this.inputs.put(counter.toString(), i);
			counter++;
		}
		options = new HashMap<String, String>();
	}
	
	/**
	 * Constructor of the class with input names. 
	 * Not intended to be used. To create instances use {@link TransformationFactory} instead.
	 * 
	 * @param name the name of the transformation.
	 * @param engine the engine that will run this transformation.
	 * @param uris the List of URIs that contain the transformation specifications.
	 * @param description the textual description of this transformation. Can be null.
	 * @param isProtected if true the transformation will be considered session protected. If false it will be treated normally.
	 * @param inputs a map with the pairs (name,input type)
	 */
	public Transformation(String name, ITransformationEngine engine, List<URI> uris, String description, ResourceType type, HashMap<String, EClass> inputs) {
		this.name = name;
		this.engine = engine;
		this.transformationURIs = uris;
		this.inputs = new LinkedHashMap<String, EClass>();
		this.outputs = new LinkedHashMap<String, EClass>();
		if (description == null) {
			this.description = "";
		}
		else {
			this.description = description;
		}
		this.type = type;
		this.inputs.putAll(inputs);
		options = new HashMap<String, String>();
	}
	
	/**
	 * 
	 * Constructor of the class with input names and outputs. 
	 * Not intended to be used. To create instances use {@link TransformationFactory} instead.
	 * 
	 * @param name the name of the transformation.
	 * @param engine the engine that will run this transformation.
	 * @param uris the List of URIs that contain the transformation specifications.
	 * @param description the textual description of this transformation. Can be null.
	 * @param isProtected if true the transformation will be considered session protected. If false it will be treated normally.
	 * @param inputs a map with the pairs (name,input type)
	 * @param outputs a map with the pairs (name,output type)
	 */
	public Transformation(String name, ITransformationEngine engine, List<URI> uris, String description, ResourceType type, HashMap<String, EClass> inputs, HashMap<String, EClass> outputs) {
		this.name = name;
		this.engine = engine;
		this.transformationURIs = uris;
		this.inputs = new LinkedHashMap<String, EClass>();
		this.outputs = new LinkedHashMap<String, EClass>();
		if (description == null) {
			this.description = "";
		}
		else {
			this.description = description;
		}
		this.type = type;
		this.inputs.putAll(inputs);
		this.outputs.putAll(outputs);
		options = new HashMap<String, String>();
	}
	
	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#getName()
	 */
	@Override
	public String getName() {
		return name;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#getEngine()
	 */
	@Override
	public String getEngine() {
		return engine.getName();
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#getTransformationFile()
	 */
	@Override
	public List<URI> getTransformationURIs() {
		return transformationURIs;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#getRequiredInputList()
	 */
	@Override
	public List<EClass> getRequiredInputList() {
		Vector<EClass> ret = new Vector<EClass>();
		ret.addAll(inputs.values());
		return ret;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#getDescription()
	 */
	@Override
	public String getDescription() {
		return description;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#isProtected()
	 */
	@Override
	public boolean isProtected() {
		return type.equals(ResourceType.PROTECTED);
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#addTransformationOption(java.lang.String, java.lang.Object)
	 */
	@Override
	public void addTransformationOption(String option, String value) {
		options.put(option, value);
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modeltransformator.service.ITransformation#getOptions()
	 */
	@Override
	public HashMap<String, String> getOptions() {
		return options;
	}

	@Override
	public LinkedHashMap<String, EClass> getInputs() {
		return inputs;
	}

	@Override
	public List<EClass> getProducedOutputList() {
		Vector<EClass> ret = new Vector<EClass>();
		ret.addAll(outputs.values());
		return ret;
	}

	@Override
	public LinkedHashMap<String, EClass> getOutputs() {
		return outputs;
	}

	@Override
	public ResourceType getResourceType() {
		return type;
	}

}
